-- Arquivo de registradores (8 registradores de n bits)
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.std_logic_unsigned.all;
use IEEE.NUMERIC_STD.all;

-- Pacote com definicoes gerais do processador
use work.definicoes_gerais.all;

entity bloco_registradores is
    generic (num_bits : INTEGER := 32 );
	 Port ( CLK       : in   STD_LOGIC;
           RESET     : in   STD_LOGIC;
           STO       : in   STD_LOGIC;
           RD_A      : in   STD_LOGIC;
			  RD_B      : in   STD_LOGIC;
           WR_ADDR   : in   reg_geral;
           A_RD_ADDR : in   reg_geral;
			  B_RD_ADDR : in   reg_geral;
           ENTRADA   : in   STD_LOGIC_VECTOR ((num_bits - 1) downto 0);
			  A_OUT     : out  STD_LOGIC_VECTOR ((num_bits - 1) downto 0);
           B_OUT     : out  STD_LOGIC_VECTOR ((num_bits - 1) downto 0));
end bloco_registradores;

architecture Behavioral of bloco_registradores is
	subtype registrador is std_logic_vector((num_bits - 1) downto 0);
	type array_registrador is array (0 to 7) of registrador;
	SIGNAL RF : array_registrador;
begin

	-- Processa escrita
	process (CLK,RESET)
	variable load_read : std_logic_vector(1 downto 0);
	begin
		if (RESET = '1') then
			RF(0) <= (others => '0');
			RF(1) <= (others => '0');
			RF(2) <= (others => '0');
			RF(3) <= (others => '0');
			RF(4) <= (others => '0');
			RF(5) <= (others => '0');
			RF(6) <= (others => '0');
			RF(7) <= (others => '0');
		else
			if rising_edge(CLK) then
				if STO = '1' then
					RF(CONV_INTEGER(WR_ADDR)) <= ENTRADA;
				end if;				
			end if;			
		end if;
	end process;
	
	-- Processa leitura da porta A
	process (RD_A,A_RD_ADDR)
	begin
		if (RD_A = '1') then
			A_OUT <= RF(CONV_INTEGER(A_RD_ADDR));
		else
			A_OUT <= (others => 'Z');
		end if;
	end process;
	
	-- Processa leitura da porta B
	process (RD_B,B_RD_ADDR)
	begin
		if (RD_B = '1') then
			B_OUT <= RF(CONV_INTEGER(B_RD_ADDR));
		else
			B_OUT <= (others => 'Z');
		end if;
	end process;
	
end Behavioral;

